package bp.wf;

import bp.da.*;
import bp.port.Emp;
import bp.sys.*;
import bp.tools.HttpClientUtil;
import bp.web.WebUser;
import bp.wf.template.*;
import bp.difference.*;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import net.sf.json.JSONObject;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 事件重写.
*/
public class OverrideEvent
{
	public static String SendToEmail(SMS sms){
		return "";
	}
	public static String SendToDingDing(SMS sms) throws Exception
	{
		bp.da.Log.DefaultLogWriteLine(LogType.Info, "发送钉钉消息");
		String sendTo = sms.getSendToEmpNo();
		Emp emp = new Emp(sendTo);
		//获取钉应用toekn
		DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
		OapiGettokenRequest apiRequest = new OapiGettokenRequest();
		//传入参数
		apiRequest.setAppkey(SystemConfig.getDing_AppKey());
		apiRequest.setAppsecret(SystemConfig.getDing_AppSecret());
		apiRequest.setHttpMethod("GET");
		OapiGettokenResponse oapiResponse = client.execute(apiRequest);
		//获取返回结果
		String data=oapiResponse.getBody();
		JSONObject json = JSONObject.fromObject(data);
		bp.da.Log.DefaultLogWriteLine(LogType.Info, "获取钉钉Token"+json);
		//获取token
		String token=json.getString("access_token");

		//发送消息
		client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
		OapiMessageCorpconversationAsyncsendV2Request sendRequest = new OapiMessageCorpconversationAsyncsendV2Request();
		//应用id
		sendRequest.setAgentId(Long.parseLong(SystemConfig.getDing_AgentID()));
		//发送给谁
		if(!DataType.IsNullOrEmpty(emp.getAppUserID())){
			bp.da.Log.DefaultLogWriteLine(LogType.Info, "钉钉:发送给USERID----"+emp.getAppUserID());
			sendRequest.setUseridList(emp.getAppUserID());
		}
		else {
			bp.da.Log.DefaultLogWriteLine(LogType.Info, "钉钉:发送给No-"+emp.getNo());
			sendRequest.setUseridList(emp.getNo());
		}
		sendRequest.setToAllUser(false);

		bp.da.Log.DefaultLogWriteLine(LogType.Info, "钉钉:发送给No-"+sendRequest.toString());

		GenerWorkFlow generWorkFlow=new GenerWorkFlow(sms.getWorkID());

		//发送OA类型的消息
		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		//点击消息时的回调地址
		String messageUrl=SystemConfig.getAppSettings().get("messageOfDingDingPath")+"?actionType=todo&fk_flow="+generWorkFlow.getFlowNo()+"&workId="+generWorkFlow.getWorkID()+"&m="+DataType.getCurrentDateTimess();
		msg.setOa(new OapiMessageCorpconversationAsyncsendV2Request.OA());
		msg.getOa().setHead(new OapiMessageCorpconversationAsyncsendV2Request.Head());
		//设置head
		msg.getOa().getHead().setText("审核通知");
		msg.getOa().getHead().setBgcolor("FFBBBBBB");
		//设置消息回调地址
		msg.getOa().setMessageUrl(messageUrl);
		msg.getOa().setBody(new OapiMessageCorpconversationAsyncsendV2Request.Body());
		//设置消息体标题
		msg.getOa().getBody().setTitle(generWorkFlow.getTitle());
		//设置消息体内容
		msg.getOa().getBody().setContent("您有一条待办工作需审核。");
		//设置消息体格式
		List<OapiMessageCorpconversationAsyncsendV2Request.Form> list=new ArrayList<>();
		OapiMessageCorpconversationAsyncsendV2Request.Form form=new OapiMessageCorpconversationAsyncsendV2Request.Form();
		form.setKey("发起人");
		form.setValue(generWorkFlow.getStarterName());
		list.add(form);
		form=new OapiMessageCorpconversationAsyncsendV2Request.Form();
		form.setKey("发送时间");
		form.setValue(DataType.getCurrentDateTime());
		list.add(form);
		msg.getOa().getBody().setForm(list);

		//设置消息类型
		msg.setMsgtype("oa");

		sendRequest.setMsg(msg);

		bp.da.Log.DefaultLogWriteLine(LogType.Info, "钉钉消息----"+messageUrl);

		OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(sendRequest, token);
		System.out.println(rsp.getBody());
		bp.da.Log.DefaultLogWriteLine(LogType.Info, "发送钉钉消息"+rsp.getBody());
		return "发送成功";
	}
	public static String SendToWeiXin(SMS sms) throws Exception{
		GenerWorkFlow generWorkFlow=new GenerWorkFlow(sms.getWorkID());
		boolean flag=false;
		//微信企业号
		if(!DataType.IsNullOrEmpty(SystemConfig.getWX_AgentID()))
		{
			//第一步，先获取token
			String access_token ="";
			String url="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+SystemConfig.getWX_CorpID()+"&corpsecret="+SystemConfig.getWX_AppSecret();
			String json= HttpClientUtil.doGet(url);
			JSONObject jsonObject = JSONObject.fromObject(json);
			if(jsonObject.getString("errcode").equals("0")) {
				access_token = jsonObject.getString("access_token");

				//第二步，组装消息体
				String messageUrl=SystemConfig.getAppSettings().get("messageOfQYWXPath").toString();
				String state="MyFlow_"+generWorkFlow.getFlowNo()+"_"+generWorkFlow.getWorkID();
				String reddirectUrl="https://open.weixin.qq.com/connect/oauth2/authorize?"
						+"appid="+SystemConfig.getWX_CorpID()+"&redirect_uri="+messageUrl+""
						+"&response_type=code&scope=snsapi_base&state="+state+""
						+"&agentID="+SystemConfig.getWX_AgentID()+"#wechat_redirect";
				String msgBody="{" +
						"   \"touser\" : \"UserID1|UserID2|UserID3\"," +
						"   \"toparty\" : \"PartyID1 | PartyID2\"," +
						"   \"totag\" : \"TagID1 | TagID2\"," +
						"   \"msgtype\" : \"textcard\"," +
						"   \"agentid\" : 1," +
						"   \"textcard\" : {" +
						"            \"title\" : \"审核通知\"," +
						"            \"description\" : \"<div class=\\\"gray\\\">\""+DataType.getCurrentDateTime()+"\"</div> <div class=\\\"normal\\\">\""+sms.getTitle()+"\"</div><div class=\\\"highlight\\\">需要您进行审核。</div>\"," +
						"            \"url\" : \""+reddirectUrl+"\"," +
						"                        \"btntxt\":\"查看详情\"" +
						"   }," +
						"   \"enable_id_trans\": 0," +
						"   \"enable_duplicate_check\": 0," +
						"   \"duplicate_check_interval\": 1800" +
						"}";

				//第三步，执行消息推送
				url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="+access_token;

				String jsonData=bp.tools.PubGlo.HttpPostConnect(url, msgBody,"POST",true);
				jsonObject = JSONObject.fromObject(jsonData);
			}

		}
		//微信公众号
		if(!DataType.IsNullOrEmpty(SystemConfig.getWXGZH_Appid()))
		{
			//第一步，先获取token
			String access_token ="";
			String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + SystemConfig.getWXGZH_Appid() + "&secret=" + SystemConfig.getWXGZH_AppSecret();
			String json= HttpClientUtil.doGet(url);
			JSONObject jsonObject = JSONObject.fromObject(json);
			if(jsonObject.getString("errcode").equals("0")) {
				access_token = jsonObject.getString("access_token");
				String redircet_uri = SystemConfig.getAppSettings().get("messageOfWXPath").toString();
				String state="MyFlow_"+generWorkFlow.getFlowNo()+"_"+generWorkFlow.getWorkID();
				String reddirectUrl="https://open.weixin.qq.com/connect/oauth2/authorize?"
						+"appid="+SystemConfig.getWXGZH_Appid()+"&redirect_uri="+redircet_uri+""
						+"&response_type=code&scope=snsapi_userinfo&state="+state+""
						+"&connect_redirect=1#wechat_redirect";
				//需要根据选中的消息模版，定义参数格式
//                    String postData = "{\"touser\":\"" + this.getSenderTo() + "\",\"template_id\":\"" + SystemConfig.getWeiXin_TemplateId() + "\"," +
//                            "\"url\":\"" + redircet_uri + "\",\"data\":{\"thing5\":{\"value\":\"审核通知\"}," +
//                            "\"time3\":{\"value\":\"" + DataType.getCurrentDateTime() + "\"}}}";
				String postData ="";
				String jsonData=bp.tools.PubGlo.HttpPostConnect(url, postData,"POST",true);
				jsonObject = JSONObject.fromObject(jsonData);
			}
		}
		return "发送成功";
	}
	public static String MessageIsEnableSelf(SMS sms){
		return "";
	}
	/**
	 流程事件-总体拦截器.

	 @param eventMark 流程标记
	 @param wn worknode
	 @param paras 参数
	 @param checkNote 审核意见.
	 @return 执行信息.
	*/
	public static String DoIt(String eventMark, WorkNode wn, String paras, String checkNote, int returnToNodeID, String returnToEmps, String returnMsg) throws Exception {
		//发送成功.
		if (eventMark.equals(EventListNode.SendSuccess) == true)
		{
			// xxx   WFState=0 空白.
		//	long workid=bp.wf.Dev2Interface.Node_CreateBlankWork("qingjia");
		//	bp.wf.Dev2Interface.Node_SetDraft(workid); //WFSTate=1
			//创建一个新的workid.
		//	long workid2=bp.wf.Dev2Interface.Node_CreateBlankWork("qingjia");
			return SendSuccess(wn);
		}

		//退回后事件.
		if (eventMark.equals(EventListNode.ReturnAfter) == true)
		{
			if(returnToNodeID == 0 && DataType.IsNullOrEmpty(paras) == false){
				AtPara atPara = new AtPara(paras);
				returnToNodeID = atPara.GetValIntByKey("ToNode");
			}

			return ReturnAfter(wn, returnToNodeID, returnToEmps, returnMsg);
		}

		// 流程结束事件.
		if (eventMark.equals(EventListFlow.FlowOverAfter) == true)
		{
			return FlowOverAfter(wn);
		}

		return null;
	}
	private static FlowSort GetParentFlowSort(String flowSortNo) throws Exception {
		FlowSort fs = new FlowSort(flowSortNo);
		if(fs.getParentNo().equals("1"))
			return fs;
		return GetParentFlowSort(fs.getParentNo());
	}
	/**
	 执行发送.

	 @param wn
	 @return
	*/
	public static String SendSuccess(WorkNode wn) throws Exception {
		if (SystemConfig.getCustomerNo().equals("NingBoGang") == true)
		{
			// 新增待办待阅信息接口地址
			String newToDoUrl = SystemConfig.getAppSettings().get("NewToDoUrl").toString();
			// 待办待阅转已读接口接口地址
			String toDoConReadUrl = SystemConfig.getAppSettings().get("ToDoConReadUrl").toString();
			String[] todoemps = wn.getHisGenerWorkFlow().getTodoEmps().split(";");
			for(String todoemp : todoemps){
				//如果是开始节点，调用新增待办待阅信息接口
				if (wn.getHisNode().getItIsStartNode() == true){
					// 调用新增待办待阅信息接口
					nbgStartInt( wn, todoemp, newToDoUrl);

				}else if(wn.getHisNode().getItIsEndNode() == true){
					// 如果是结束节点,调用待办待阅转已读接口
					nbgEndInt(wn, todoemp, toDoConReadUrl,"1");
				}else{
					// 调用待办待阅转已读接口
					nbgEndInt(wn, todoemp, toDoConReadUrl, "1");
					//调用新增待办待阅信息接口
					nbgStartInt( wn, todoemp, newToDoUrl);
				}
			}
		}
		if (SystemConfig.getCustomerNo().equals("TianYu") == true)
		{
			if (wn.getHisNode().getItIsStartNode() == false)
				return null; //如果不是开始节点发送,就不处理.

			//模板目录.
			String sortNo = wn.getHisFlow().getFlowSortNo();

			//找到系统编号.
			FlowSort fs = GetParentFlowSort(sortNo);

			//子系统:当前目录的上一级目录必定是子系统,系统约定的.
			SubSystem system = new SubSystem(fs.getNo());

			//检查是否配置了?
			if (DataType.IsNullOrEmpty(system.getTokenPiv()) == true)
				return null;

			//执行事件.
			DoPost("SendSuccess", wn, system);
		}
		return null;
	}

	/**
	 执行退回操作.

	 @param wn
	 @param toNodeID
	 @param toEmp
	 @param info
	 @return
	*/
	public static String ReturnAfter(WorkNode wn, int toNodeID, String toEmp, String info) throws Exception {
		if (SystemConfig.getCustomerNo().equals("NingBoGang") == true)
		{
			// 新增待办待阅信息接口地址
			String newToDoUrl = SystemConfig.getAppSettings().get("NewToDoUrl").toString();
			// 待办待阅转已读接口接口地址
			String toDoConReadUrl = SystemConfig.getAppSettings().get("ToDoConReadUrl").toString();
			String[] todoemps = wn.getHisGenerWorkFlow().getTodoEmps().split(";");
			for(String todoemp : todoemps){
				//如果是开始节点，调用新增待办待阅信息接口
				if (wn.getHisNode().getItIsStartNode() == true){
					// 调用新增待办待阅信息接口
					nbgStartInt( wn, todoemp, newToDoUrl);

				}else if(wn.getHisNode().getItIsEndNode() == true){
					// 如果是结束节点,调用待办待阅转已读接口
					nbgEndInt(wn, todoemp, toDoConReadUrl, "2");
				}else{
					// 调用待办待阅转已读接口
					nbgEndInt(wn, todoemp, toDoConReadUrl, "2");
					//调用新增待办待阅信息接口
					nbgStartInt( wn, todoemp, newToDoUrl);
				}
			}
		}
		if (SystemConfig.getCustomerNo().equals("TianYu") == true)
		{
			if (String.valueOf(toNodeID).endsWith("01") == false)
			{
				return null; //如果不是退回的开始节点.
			}

			//模板目录.
			String sortNo = wn.getHisFlow().getFlowSortNo();

			//找到系统编号.
			//找到系统编号.
			FlowSort fs = GetParentFlowSort(sortNo);

			//子系统:当前目录的上一级目录必定是子系统,系统约定的.
			SubSystem system = new SubSystem(fs.getNo());

			//检查是否配置了?
			if (DataType.IsNullOrEmpty(system.getTokenPiv()) == true)
			{
				return null;
			}

			//执行事件.
			DoPost("ReturnAfter", wn, system);
		}
		return null;
	}

	public static String FlowOverAfter(WorkNode wn) throws Exception {
		if (SystemConfig.getCustomerNo().equals("TianYu") == true)
		{
			//模板目录.
			String sortNo = wn.getHisFlow().getFlowSortNo();

			//找到系统编号.
			//找到系统编号.
			FlowSort fs = GetParentFlowSort(sortNo);

			//子系统:当前目录的上一级目录必定是子系统,系统约定的.
			SubSystem system = new SubSystem(fs.getNo());

			//检查是否配置了?
			if (DataType.IsNullOrEmpty(system.getTokenPiv()) == true)
			{
				return null;
			}

			//执行事件.
			DoPost("FlowOverAfter", wn, system);
		}
		return null;
	}

	/**
	 * 宁波港调用新增待办待阅信息接口
	 * @param wn 工作节点（包含工作信息、流程信息）
	 * @param todoemp
	 * @param newToDoUrl 接口地址
	 * @return
	 * @throws Exception
	 */
	public static String nbgStartInt(WorkNode wn,String todoemp,String newToDoUrl) throws Exception {
		java.util.Map<String, String> headerMap = new Hashtable<String, String>();
		//Base64 base64 = new Base64();
		String[] sendArr = wn.getHisGenerWorkFlow().getSender().replace(";","").split(",");
		String[] todoArr = todoemp.split(",");
		headerMap.put("Content-Type", "application/json");
		String param = "";
		param += "{";
		param += "\"systemCode\":\"3ed0bed623d6d594bed9a90b0caaef3c\",";
		param += "\"contentId\":\"" + wn.getWorkID()+ "_" + wn.getHisNode().getNodeID() + "\",";
		param += "\"messageTitle\":\"" + wn.getHisWork().GetValByKey("Title") + "\",";
		param += "\"messageSenderId\":\"" + sendArr[0] + "\",";
		param += "\"messageReceiverId\":\"" +todoArr[0]  + "\",";
		param += "\"messageSenderName\":\"" +  sendArr[1] + "\",";
		param += "\"messageReceiverName\":\"" + todoArr[1] + "\",";
		param += "\"messageUrlPortal\":\"\",";
		param += "\"messageUrlZgb\":\"" + SystemConfig.getAppSettings().get("VueHostURL").toString()+"/#/MobileSSO?DoWhat=DealWork&DoParam={WorkID:"+wn.getWorkID()+",FK_Flow:"+wn.getHisNode().getFlowNo()+"}\",";
		param += "\"messageKind\":\"2\",";
		param += "\"messageStatus\":\"0\",";
		param += "\"messageType\":\"28\",";
		param += "\"contentType\":\"\",";
		param += "\"step\":\"\"";
		param += "}";

		String redata = HttpClientUtil.doPost(newToDoUrl,param,headerMap);
		net.sf.json.JSONObject j = net.sf.json.JSONObject.fromObject(redata);
		//请求失败，
		if(j.get("status") != null){
			String msg = "err@调用新增待办待阅信息接口失败，[" + newToDoUrl + "]接口响应：" + j + "，参数：" + param;
			bp.da.Log.DebugWriteError(msg);
			throw new RuntimeException(msg);
		}
		//请求成功
		if (j.get("code") != null && "0000".equals(j.get("code").toString())) {
			return "请求成功，接口响应：" + j;
		}else {
			//code不等于0000时返回响应结果
			return "接口响应：" + j;
		}
	}

	/**
	 * 宁波港调用待办待阅转已读接口
	 * @param wn 工作节点（包含工作信息、流程信息）
	 * @param todoemp
	 * @param newToDoUrl 接口地址
	 * @param actionType 1：待办转已办 2：删除该条待办
	 * @return
	 * @throws Exception
	 */
	public static String nbgEndInt(WorkNode wn, String todoemp,String newToDoUrl, String actionType) throws Exception {
		//从轨迹表中查询节点编号,接收人手机号（从哪个节点发送过来的）
		String dbStr = bp.difference.SystemConfig.getAppCenterDBVarStr();
		Paras ps = new Paras();
		ps.SQL = "SELECT NDFrom,EmpTo FROM ND" + Integer.parseInt(wn.getHisFlow().getNo()) + "Track WHERE ActionType=1 AND NDTo=" + dbStr + "NDTo AND WorkID=" + dbStr + "WorkID ORDER BY RDT DESC";
		ps.Add("NDTo", wn.getHisNode().getNodeID());
		ps.Add("WorkID", wn.getWorkID());
		DataTable dt_NDFrom = DBAccess.RunSQLReturnTable(ps);
		if (dt_NDFrom.Rows.size() == 0)
		{
			String msg = "err@调用待办待阅转已读接口失败，在轨迹表中获取上一节点时出现错误，SQL=" + ps.SQL + "，参数=" + ps.toString();
			bp.da.Log.DebugWriteError(msg);
			throw new RuntimeException(msg);
		}
		String ndFrom = dt_NDFrom.getValue(0, "NDFrom").toString();
		String empTo = dt_NDFrom.getValue(0, "EmpTo").toString();
		java.util.Map<String, String> headerMap = new Hashtable<String, String>();
		//Base64 base64 = new Base64();
		String[] todoArr = todoemp.split(",");
		headerMap.put("Content-Type", "application/json");
		String param = "";
		param += "{";
		param += "\"systemCode\":\"3ed0bed623d6d594bed9a90b0caaef3c\",";
		param += "\"userId\":\"" + empTo + "\",";
		param += "\"messageId\":\"" + wn.getWorkID()+ "_" + ndFrom + "\",";
		param += "\"action\":\"" + actionType + "\"";
		param += "}";

		String redata = HttpClientUtil.doPost(newToDoUrl,param,headerMap);
		net.sf.json.JSONObject j = net.sf.json.JSONObject.fromObject(redata);
		//请求失败，
		if(j.get("status") != null){
			String msg = "err@调用待办待阅转已读接口失败，[" + newToDoUrl + "]接口响应：" + j + "，参数：" + param;
			bp.da.Log.DebugWriteError(msg);
			throw new RuntimeException(msg);
		}
		//请求成功
		if (j.get("code") != null && "0000".equals(j.get("code").toString())) {
			return "请求成功，接口响应：" + j;
		}else {
			//code不等于0000时返回响应结果
			return "接口响应：" + j;
		}
	}
	/**
	 执行天宇的回调.

	 @param eventMark 事件目录.
	 @param wn
	 @param system
	 @return
	*/
	public static String DoPost(String eventMark, WorkNode wn, SubSystem system) throws Exception {
		String myEventMark = "0";
		if (eventMark.equals("ReturnAfter"))
		{
			myEventMark = "3";
		}
		if (eventMark.equals("SendSuccess"))
		{
			myEventMark = "1";
		}
		if (eventMark.equals("FlowOverAfter"))
		{
			myEventMark = "2";
		}

		String apiParas = system.getApiParas(); //配置的json字符串.
		apiParas = apiParas.replace("~", "\"");

		apiParas = apiParas.replace("@WorkID", String.valueOf(wn.getWorkID())); //工作ID.
		apiParas = apiParas.replace("@FlowNo", wn.getHisFlow().getNo()); //流程编号.
		apiParas = apiParas.replace("@NodeID", String.valueOf(wn.getHisNode().getNodeID())); //节点ID.
		apiParas = apiParas.replace("@TimeSpan", String.valueOf(DBAccess.GenerOID("TS"))); //时间戳.
		apiParas = apiParas.replace("@EventMark", myEventMark); //稳超定义的，事件标记.
		apiParas = apiParas.replace("@EventID", eventMark); //EventID 定义的事件类型.
		apiParas = apiParas.replace("@SPYJ", "xxx无xx"); //审批意见.

		//如果表单的数据有,就执行一次替换.
		apiParas = bp.wf.Glo.DealExp(apiParas, wn.rptGe);
		if(apiParas.contains("@")==true){
			GenerWorkFlow gwf = new GenerWorkFlow(wn.getWorkID());
			AtPara atpara = gwf.getatPara();
			for(String key :atpara.getHisHT().keySet()){
				apiParas = apiParas.replace("@"+key, atpara.GetValStrByKey(key));
				if(apiParas.contains("@")==false)
					break;
			}
		}

		//需要补充算法. @WenChao.
		String sign = "密钥:" + system.getTokenPiv() + ",公约" + system.getTokenPublie();
		apiParas = apiParas.replace("@sign", sign); //签名，用于安全验证.

		if (apiParas.contains("@") == true)
		{
			throw new RuntimeException("err@配置的参数没有替换下来:" + apiParas);
		}

		//替换url参数.
		String url = system.getCallBack(); //回调的全路径.
		url = bp.wf.Glo.DealExp(url, wn.rptGe);

		//执行post.
		String data = bp.tools.PubGlo.HttpPostConnect(url, apiParas, system.getRequestMethod(), system.getItIsJson());
		return data;
	}
}
